﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Scheduling
{
    [DataContract]
    [KnownType(typeof(RangeEvaluator))]
    [KnownType(typeof(ListEvaluator))]
    [KnownType(typeof(GreaterThanEvaluator))]
    [KnownType(typeof(LessThanEvaluator))]
    [KnownType(typeof(NotEqualEvaluator))]
    public abstract class Evaluator
    {
        protected Inclusion inclusion = Inclusion.None;
        public abstract bool Evaluate(int value);
    }

    [DataContract]
    public class RangeEvaluator : Evaluator
    {
        [DataMember]
        public int Floor;
        [DataMember]
        public int Ceiling;

        public RangeEvaluator(string setting, Inclusion inclusion)
        {
            this.inclusion = inclusion;
            string set = Regex.Replace(setting, @"\(|\)|\[|\]", "");
            Floor = Convert.ToInt32(set.Split('-')[0]);
            Ceiling = Convert.ToInt32(set.Split('-')[1]);
        }

        public override bool Evaluate(int value)
        {
            bool success = false;
            switch (inclusion)
            {
                case Inclusion.Beginning:
                    success = value >= Floor && value < Ceiling; 
                    break;
                case Inclusion.BeginningEnd:
                    success = value >= Floor && value <= Ceiling;
                    break;
                case Inclusion.End:
                    success = value > Floor && value <= Ceiling;
                    break;
                case Inclusion.None:
                    success = value > Floor && value < Ceiling;
                    break;
            }
            return success;
        }
    }

    [DataContract]
    public class ListEvaluator : Evaluator
    {
        [DataMember]
        public List<int> Values = new List<int>();

        public ListEvaluator(string setting)
        {
            Values = new List<int>(setting.Split(',').Select(x=>Convert.ToInt32(x)));
        }

        public override bool Evaluate(int value)
        {
            return Values.Contains(value);
        }
    }

    [DataContract]
    public class GreaterThanEvaluator : Evaluator
    {
        [DataMember]
        public int Floor { get; set; }

        public GreaterThanEvaluator(string setting)
        {
            Floor  = Convert.ToInt32(Regex.Replace(setting, ">", ""));
        }

        public override bool Evaluate(int value)
        {
            return value > Floor;
        }
    }

    [DataContract]
    public class LessThanEvaluator : Evaluator
    {
        [DataMember]
        public int Ceiling { get; set; }

        public LessThanEvaluator(string setting)
        {
            Ceiling = Convert.ToInt32(Regex.Replace(setting, "<", ""));
        }

        public override bool Evaluate(int value)
        {
            return value < Ceiling; 
        }
    }

    [DataContract]
    public class NotEqualEvaluator : Evaluator
    {
        [DataMember]
        public int Value;

        public NotEqualEvaluator(string setting)
        {
            Value = Convert.ToInt32(Regex.Replace(setting, "<>", ""));
        }

        public override bool Evaluate(int value)
        {
            return this.Value != value; 
        }
    }
}
